--- @param extension Package
--- @param HY HY_Utility
--- @param U Utility
return function(extension, HY, U)
    local hy_kudamaki_tsukasa = General:new(extension, "hy_kudamaki_tsukasa", "chi_k", 4, 4, General.Female)
    local strike_unprepared = fk.CreateSkill {
        name = "strike_unprepared",
    }
    strike_unprepared:addEffect("active", {
        anim_type = "control",
        card_filter = Util.FalseFunc,
        target_num = 1,
        target_filter = function(self, player, to_select, selected, selected_cards)
            if #selected == 1 then
                return false
            end
            local targets = {}
            for _, target in ipairs(Fk:currentRoom().alive_players) do
                if player:getMark("strike_unprepared_hp") == 0 and (player.hp > target.hp) and not target:isNude() and target:isWounded() then
                    table.insertIfNeed(targets, target)
                end
                if player:getMark("strike_unprepared_card") == 0 and (#player:getCardIds("h") > #target:getCardIds("h")) then
                    table.insertIfNeed(targets, target)
                end
            end
            return table.contains(targets, to_select)
        end,
        can_use = function(self, player)
            local targets = {}
            for _, target in ipairs(Fk:currentRoom().alive_players) do
                if player:getMark("strike_unprepared_hp") == 0 and (player.hp > target.hp) and not target:isNude() and target:isWounded() then
                    table.insertIfNeed(targets, target)
                end
                if player:getMark("strike_unprepared_card") == 0 and (#player:getCardIds("h") > #target:getCardIds("h")) then
                    table.insertIfNeed(targets, target)
                end
            end
            return #targets > 0
        end,
        prompt = function(self, player, selected_cards, selected_targets)
            if player:getMark("strike_unprepared_hp") == 0 and player:getMark("strike_unprepared_card") == 0 then
                return "strike_unprepared_prompt"
            elseif player:getMark("strike_unprepared_hp") == 0 then
                return "strike_unprepared_prompt1"
            elseif player:getMark("strike_unprepared_card") == 0 then
                return "strike_unprepared_prompt2"
            end
            return ""
        end,
        target_tip = function(self, player, to_select, selected, selected_cards, card, selectable, extra_data)
            if player:getMark("strike_unprepared_hp") == 0 and player:getMark("strike_unprepared_card") == 0 then
                if #to_select:getCardIds("h") < #player:getCardIds("h") and to_select.hp < player.hp and to_select:isWounded() then
                    return "strike_unprepared_both"
                elseif #to_select:getCardIds("h") < #player:getCardIds("h") then
                    return "strike_unprepared_card"
                elseif to_select.hp < player.hp and to_select:isWounded() then
                    return "strike_unprepared_hp"
                end
            elseif player:getMark("strike_unprepared_hp") == 0 then
                if to_select.hp < player.hp and to_select:isWounded() then
                    return "strike_unprepared_hp"
                end
            elseif player:getMark("strike_unprepared_card") == 0 then
                if #to_select:getCardIds("h") < #player:getCardIds("h") then
                    return "strike_unprepared_card"
                end
            end
        end,
        on_use = function(self, room, cardUseEvent)
            local player = cardUseEvent.from
            local target = cardUseEvent.tos[1]
            if (player.hp > target.hp and target:isWounded()) and (#player.player_cards[Player.Hand] > #target.player_cards[Player.Hand]) and not target:isNude() and player:getMark("strike_unprepared_hp") == 0 and player:getMark("strike_unprepared_card") == 0 then
                local result = room:askToChoice(player, {
                    choices = { "strike_unprepared_hp", "strike_unprepared_card" },
                    skill_name = strike_unprepared.name
                })
                room:setPlayerMark(player, result, target.id)
                if result == "strike_unprepared_hp" then
                    local count = #target:getCardIds("he") < 3 and #target:getCardIds("he") or 3
                    local cards = room:askToChooseCards(player, {
                        target = target,
                        min = count,
                        max = count,
                        flag = "he",
                        skill_name = strike_unprepared.name
                    })
                    room:throwCard(cards, strike_unprepared.name, target, player)
                    if target:isWounded() then
                        room:recover({
                            who = target,
                            num = 1,
                            recoverBy = player,
                            skillName = strike_unprepared.name,
                        })
                    end
                elseif not target.dead then
                    room:drawCards(target, 3, strike_unprepared.name)
                    room:loseHp(target, 1, strike_unprepared.name)
                end
            elseif (player.hp > target.hp and target:isWounded()) and player:getMark("strike_unprepared_hp") == 0 and not target:isNude() then
                room:setPlayerMark(player, "strike_unprepared_hp", target.id)
                local count = #target:getCardIds("he") < 3 and #target:getCardIds("he") or 3
                local cards = room:askToChooseCards(player, {
                    target = target,
                    min = count,
                    max = count,
                    flag = "he",
                    skill_name = strike_unprepared.name
                })
                room:throwCard(cards, strike_unprepared.name, target, player)
                if target:isWounded() then
                    room:recover({
                        who = target,
                        num = 1,
                        recoverBy = player,
                        skillName = strike_unprepared.name,
                    })
                end
            elseif (#player.player_cards[Player.Hand] > #target.player_cards[Player.Hand]) and player:getMark("strike_unprepared_card") == 0 and not target.dead then
                room:setPlayerMark(player, "strike_unprepared_card", target.id)
                room:drawCards(target, 3, strike_unprepared.name)
                room:loseHp(target, 1, strike_unprepared.name)
            end
        end,
    })
    strike_unprepared:addEffect(fk.EventPhaseStart, {
        can_refresh = function(self, event, target, player, data)
            return player:hasSkill(strike_unprepared.name) and player == target and player.phase == Player.Play
        end,
        on_refresh = function(self, event, target, player, data)
            player.room:setPlayerMark(player, "strike_unprepared_hp", 0)
            player.room:setPlayerMark(player, "strike_unprepared_card", 0)
        end,
    })
    local fox_grace = fk.CreateSkill {
        name = "fox_grace",
        tags = {
            Skill.Limited,
        }
    }
    fox_grace:addEffect("active", {
        can_use = function(self, player)
            return player:usedSkillTimes(fox_grace.name, Player.HistoryGame) < 1
        end,
        card_filter = Util.FalseFunc,
        target_num = 1,
        target_filter = function(self, player, to_select, selected, selected_cards)
            return #selected == 0
        end,
        prompt = function(self, selected, selected_cards)
            return "fox_grace_prompt"
        end,
        on_use = function(self, room, cardUseEvent)
            local player = cardUseEvent.from
            local target = cardUseEvent.tos[1]
            room:changeMaxHp(target, 1)
            room:recover({
                who = target,
                num = 2,
                skillName = fox_grace.name,
                recoverBy = player,
            })
            room:drawCards(target, 4, fox_grace.name)
            room:handleAddLoseSkills(target, "self_destroy")
        end,
    })
    local self_destroy = fk.CreateSkill {
        name = "self_destroy",
    }
    self_destroy:addEffect(fk.EventPhaseStart, {
        anim_type = "negative",
        can_trigger = function(self, event, target, player, data)
            return player:hasSkill(self_destroy.name) and player == target and player.phase == Player.Finish
        end,
        on_cost = function(self, event, target, player, data)
            event:setCostData(self, {})
            local room = player.room
            local choices = {
                "self_destroy_card",
                "self_destroy_turnOver",
                "self_destroy_hp",
                "self_destroy_maxHp",
            }
            local choices_temp = table.clone(choices)
            if #player:getCardIds("he") < 2 then
                table.removeOne(choices_temp, "self_destroy_card")
            end
            local count = 2
            if table.every(room:getOtherPlayers(player), function(t)
                    return t.hp >= player.hp
                end) then
                count = 1
            end
            if table.every(room:getOtherPlayers(player), function(t)
                    return #t:getCardIds("h") >= #player:getCardIds("h")
                end) then
                count = 1
            end
            count = math.max(0, count)
            count = math.min(#choices_temp, count)
            if count == 0 then
                return
            end
            event:setCostData(self, player.room:askToChoices(player, {
                choices = choices_temp,
                min_num = count,
                max_num = count,
                skill_name = self_destroy.name,
                all_choices = choices,
                cancelable = false,
            }))
            return #event:getCostData(self) > 0
        end,
        on_use = function(self, event, target, player, data)
            local room = player.room
            while #event:getCostData(self) > 0 do
                if table.contains(event:getCostData(self), "self_destroy_card") then
                    room:askToDiscard(player, {
                        min_num = 2,
                        max_num = 2,
                        include_equip = true,
                        skill_name = self_destroy.name,
                        cancelable = false
                    })
                    table.removeOne(event:getCostData(self), "self_destroy_card")
                    goto continue
                end
                if table.contains(event:getCostData(self), "self_destroy_turnOver") then
                    player:turnOver()
                    table.removeOne(event:getCostData(self), "self_destroy_turnOver")
                    goto continue
                end
                if table.contains(event:getCostData(self), "self_destroy_hp") then
                    room:loseHp(player, 1, self_destroy.name)
                    table.removeOne(event:getCostData(self), "self_destroy_hp")
                    goto continue
                end
                if table.contains(event:getCostData(self), "self_destroy_maxHp") then
                    room:changeMaxHp(player, -1)
                    table.removeOne(event:getCostData(self), "self_destroy_maxHp")
                    goto continue
                end
                ::continue::
            end
        end
    })
    extension:loadSkillSkels { strike_unprepared, fox_grace, self_destroy }
    hy_kudamaki_tsukasa:addSkill("strike_unprepared")
    hy_kudamaki_tsukasa:addSkill("fox_grace")
    hy_kudamaki_tsukasa:addRelatedSkill("self_destroy")
    Fk:loadTranslationTable {
        ["hy_kudamaki_tsukasa"] = "菅牧典",
        ["#hy_kudamaki_tsukasa"] = "恩危并施",
        ["illustrator:hy_kudamaki_tsukasa"] = "未早",
        ["designer:hy_kudamaki_tsukasa"] = "黑曜人形",
        ["cv:hy_kudamaki_tsukasa"] = "",

        ["strike_unprepared"] = "攻虚",
        [":strike_unprepared"] = "出牌阶段各限一次，你可以选择一名体力值小于你且已受伤/手牌数小于你的角色，弃置其三张牌（不足则全弃）并令其回复1点体力/令其摸三张牌并失去1点体力。",
        ["strike_unprepared_hp"] = "弃牌",
        ["strike_unprepared_card"] = "失去体力",
        ["strike_unprepared_both"] = "均可",
        ["strike_unprepared_prompt"] = "攻虚：选择一名体力值小于你且已受伤或手牌数小于你的角色",
        ["strike_unprepared_prompt1"] = "攻虚：选择一名体力值小于你且已受伤的角色",
        ["strike_unprepared_prompt2"] = "攻虚：选择一名手牌数小于你的角色",

        ["fox_grace"] = "狐惠",
        [":fox_grace"] = "限定技，出牌阶段，你可以选择一名角色，令其增加1点体力上限，回复2点体力并摸四张牌，然后其获得“<a href = ':self_destroy'>崩毁</a>”。",
        ["fox_grace_prompt"] = "狐惠：选择一名角色",

        ["self_destroy"] = "崩毁",
        [":self_destroy"] = "结束阶段，你选择两项（若你体力值或手牌数为全场最少则改为一项）：1.弃置两张牌；2.失去1点体力；3.减少1点体力上限；4.翻面。",
        ["self_destroy_card"] = "弃置两张牌",
        ["self_destroy_hp"] = "失去1点体力",
        ["self_destroy_maxHp"] = "减少1点体力上限",
        ["self_destroy_turnOver"] = "翻面",
    }
end
